Skip to content

feat: data-inspector plugin (jora live-query workbench), ctx.services, storage scopes#101

Open
antfubot wants to merge 11 commits into
mainfrom
free-points-return
Open

feat: data-inspector plugin (jora live-query workbench), ctx.services, storage scopes#101
antfubot wants to merge 11 commits into
mainfrom
free-points-return

Conversation

@antfubot

@antfubot antfubot commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Intent

Adds @devframes/plugin-data-inspector — an interactive jora query workbench over live server-side objects — together with the two core primitives its design required. Grew out of the in-PR spike (kept in history; the prototype example is replaced by the real plugin).

Devframe core

  • ctx.services — typed, namespaced cross-plugin service registry (provide / get / whenAvailable, augmentable DevframeServicesRegistry, DF0037 on duplicate providers). whenAvailable absorbs setup-order differences, giving every plugin pair a dependency-free communication channel.
  • Storage scopesgetStorageDir now takes 'workspace' | 'project' | 'global': workspace is the committable .devframe/ dir (team-shared), project the per-checkout node_modules dir (previous 'workspace' semantics), global per-user. All hosts and call sites migrated.

The plugin

  • Sources: process-global registry (globalThis Symbol store) — registerDataSource({ id, title, data: value | (async) factory, static?, queries?, icon? }) works with no context from anywhere (plugins, hosts, CLIs, agents); also exposed as a typed context service; registry changes push to connected UIs.
  • Workbench: Vue + @antfu/design; discovery CodeMirror jora editor with remote stat-mode autocomplete; struct viewer with type badges and clean meta-free rendering; data-shape panel; filter options; per-source drafts; shareable URL state; saved queries in workspace/project scopes.
  • Standalone CLI: devframe-data-inspector stats.json trace.jsonl (one static source per file), attach (connect the UI to another process running the in-process agent — loopback + pre-shared-token auth by default, discovery-file handshake), build (self-contained static export; the isomorphic engine runs queries client-side, so saved recipes stay portable).
  • Agent: @devframes/plugin-data-inspector/agent — explicit import or DEVFRAME_DATA_INSPECTOR=1 node --import … for zero-code-change attach. Documented as eval-grade access; treat like a debugger port.

Verification

716/716 tests (new units for registry, engine incl. static-portability, saved queries, file loaders; core services tests), API snapshots updated, lint/typecheck/build green, CLI file-mode smoke-tested in a browser end to end. The minimal Vite hub example dogfoods the plugin with the live ViteDevServer registered as a source.


Created with the help of an agent.

…very viewer)

Validates the live-query data-viewer architecture end to end:
server-side jora over live registered objects (incl. the ViteDevServer
serving the page), result normalizer, devframe RPC round-trip, remote
stat-mode autocomplete, and a themed discovery struct view in
devframe-style chrome. Stage-1 node spike passes 13/13 checks; findings
and hazards documented in the prototype README.

Throwaway code — lives on this spike branch as a primary source, not
for merging into main.
@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit 1832a08
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a58d1e01199fe000895aa02
😎 Deploy Preview https://deploy-preview-101--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

… source contract, saved queries

Renames the spike to data-inspector and reworks it along the agreed
direction:

- data sources follow { id, title, description?, getData(), static? }
  with dynamic register/unregister + change listeners; static sources
  memoize getData()
- saved queries (title/description, id-keyed) persisted per scope:
  user -> node_modules/.data-inspector, project -> .devframe/data-inspector
  (committable, shared with the team)
- SPA rebuilt as Vue 3 + @antfu/design on the canonical uno preset:
  split-pane workbench, debounced auto-run, client-side jora syntax gate,
  non-destructive errors (last good result stays), stats bar with query
  time + payload size, remote suggestions, synced dark mode

Full e2e verified in-browser; spike still 13/13. Findings captured in
the prototype README.
@antfubot antfubot changed the title chore: spike data-viewer prototype (jora live-query + discovery viewer) chore: spike data-inspector prototype (jora live-query + discovery viewer) Jul 16, 2026
antfubot and others added 9 commits July 16, 2026 05:30
…ush padding

- empty query now runs $ so every source lands on its entire object
- query settings (ignore functions / _-prefixed / $-prefixed keys),
  persisted client-side and applied to both results and the skeleton
- 'available data' panel: query-independent type skeleton of the active
  source (ancestor-path cycle detection keeps shared refs expanded)
- manual re-run button in the stats bar
- left column sections (editor, skeleton, saved queries) resize via the
  same @antfu/design LayoutSplitPane setup as the outer split
- discovery page padding zeroed via --discovery-page-padding-*
…badges, URL state

- FilterOptions { excludeFunctions, excludeUnderscoreProps, excludeDollarProps }
  replace the old settings names; saved queries become source-agnostic
  recipes { query, title?, description?, ...FilterOptions } with title
  optional (untitled ids derive from a stable query hash)
- data sources can provide suggested queries ({ queries?: Query[] }),
  listed read-only next to saved ones; loading any recipe applies its
  filter options
- save query now opens an OverlayModal dialog (query preview, active
  filters, title/description, scope)
- discovery struct annotations badge exotic values: Function, Map(n),
  Set(n), Date, class names, circular refs
- source, query, and filters persist in the URL (shareable/restorable)
…panel, modal filters

- query drafts persist in localStorage per data source; switching sources
  restores (or resets) the draft, and a query arriving via the URL seeds
  the draft for its source so shared links win
- SkeletonPanel replaced by DataSourceInfoPanel: source title/description
  plus a one-level data shape in a plain code block (no discovery);
  clicking a prop sets it as the query and runs
- the save-query modal always shows all three filter options with their
  on/off state
- display transform strips $class/$type meta before rendering: class
  instances show only real props, function stubs collapse to {}, Map/Set
  wrappers unwrap to their entries/values, Date/RegExp/BigInt/... render
  as bare values; badges carry the type info instead, via WeakMap
  side-tables (object identity for objects, parent+key for primitives)
- discovery's built-in query actions are enabled: the struct value-actions
  popup now offers 'Create a subquery from the path' (pipes the path onto
  the query) and 'Append path to current query' (textual append), both
  emitting up to set the editor and re-run
…nified query list

- executions (auto-run included) no longer clear the suggestion dropdown;
  it closes on accept, Escape, blur, or source switch
- the popover gets an explicit solid surface (white / #1e1e1e) with
  stronger elevation so nothing reads through it in either scheme
- suggested and saved queries render through one unified list (resolves
  the TODO), with per-entry icon, filter markers, scope/suggested badge,
  and delete only for saved entries
Promotes the data-inspector spike to a real plugin and lands the two core
primitives it design-required:

devframe core:
- ctx.services — typed, namespaced cross-plugin service registry
  (provide/get/whenAvailable, augmentable DevframeServicesRegistry,
  DF0037 on duplicate providers); whenAvailable absorbs setup-order
  differences between provider and consumer
- getStorageDir scopes become workspace/project/global: workspace is the
  committable .devframe/ dir (team-shared), project is the per-checkout
  node_modules dir (the old 'workspace'), global stays per-user; all
  hosts and call sites migrated (settings and dock prefs now persist
  under 'project')

@devframes/plugin-data-inspector:
- process-global source registry (globalThis Symbol store): sources are
  { id, title, description?, icon?, data: value | (async) factory,
  static?, queries? }; registerDataSource() needs no context, the same
  store is provided as the 'devframes:plugin:data-inspector:sources'
  context service, and changes broadcast to connected UIs
- isomorphic engine (normalize/skeleton/jora bridges) — the Map/Set
  methods duck-type live collections AND their normalized tags, so
  saved queries stay portable between live and static modes
- Vue + @antfu/design SPA with discovery's CodeMirror jora editor
  (remote stat-mode suggestions), struct viewer with type badges,
  shape panel, filters, per-source drafts, URL state, saved queries
  (workspace/project scopes via the new storage classes)
- standalone CLI: inspect .json/.jsonl files, attach to a process
  running the in-process agent (loopback + pre-shared-token auth by
  default, discovery file handshake), and build self-contained static
  exports that run the engine client-side
- unit tests for registry/engine/saved-queries/file loaders; core
  services tests; API snapshots updated

The prototype example is replaced by the plugin; the minimal Vite hub
dogfoods it with the live ViteDevServer registered as a source.
@antfubot antfubot changed the title chore: spike data-inspector prototype (jora live-query + discovery viewer) feat: data-inspector plugin (jora live-query workbench), ctx.services, storage scopes Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants